﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace PPSkin
{
    public partial class PPGroupBox : GroupBox
    {
        private string text = "PPGroupbox";

        [Description("标题"), Browsable(true), Category("自定义")]
        public override string Text
        {
            get { return text; }
            set
            {
                text = value;
                this.Invalidate();
            }
        }

        private int titleOffset = 0;

        [Description("标题x轴位置偏移"), Category("自定义")]
        public int TilteOffset
        {
            get { return titleOffset; }
            set
            {
                this.titleOffset = value;
                this.Invalidate();
            }
        }

        private int radius = 10;

        [Description("边框圆角半径"), Category("自定义")]
        public int Radius
        {
            get { return radius; }
            set { this.radius = value; this.Invalidate(); }
        }

        private int titleRadius = 10;

        [Description("标题边框圆角半径"), Category("自定义")]
        public int TitleRadius
        {
            get { return titleRadius; }
            set { this.titleRadius = value; this.Invalidate(); }
        }

        private Color borderColor = Color.Gray;

        [Description("边框颜色"), Category("自定义")]
        public Color BorderColor
        {
            get { return borderColor; }
            set { this.borderColor = value; this.Invalidate(); }
        }

        private Color titleBorderColor = Color.Gray;

        [Description("标题边框颜色"), Category("自定义")]
        public Color TitleBorderColor
        {
            get { return titleBorderColor; }
            set { this.titleBorderColor = value; this.Invalidate(); }
        }

        [Description("主题背景色"), Category("自定义")]
        public Color BaseColor { get; set; } = Color.White;

        [Description("标题背景色"), Category("自定义")]
        public Color TitleBaseColor { get; set; } = Color.White;

        [Description("边框宽度"), Category("自定义")]
        public int BorderWidth { get; set; } = 1;

        public DrawMode TextDrawMode { get; set; } = DrawMode.Anti;

        public enum DrawMode
        {
            Anti,
            Clear
        }

        public StringAlignment TextAlignment { get; set; } = StringAlignment.Center;

        public PPGroupBox()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.UpdateStyles();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextDrawMode == DrawMode.Anti ? System.Drawing.Text.TextRenderingHint.AntiAlias : System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            g.Clear(this.BackColor);
            SizeF fontsize = g.MeasureString(this.Text, this.Font);
            fontsize.Width += 8;
            fontsize.Height += 6;

            float x = 10;
            switch (TextAlignment)
            {
                case StringAlignment.Center: x = (this.Width - fontsize.Width) / 2; break;
                case StringAlignment.Near: x = radius; break;
                case StringAlignment.Far: x = this.Width - fontsize.Width - radius; break;
            }
            Rectangle textRect = new Rectangle((int)(x + titleOffset - BorderWidth), BorderWidth, (int)(fontsize.Width + 2f * BorderWidth), (int)(fontsize.Height + 2f * BorderWidth));
            Rectangle boxRect = new Rectangle(BorderWidth, (int)(textRect.Height / 2 + 0.5f * BorderWidth), (int)(this.Width - 2f * BorderWidth ), (int)(this.Height - textRect.Height / 2 - 1.5f * BorderWidth));

            Pen borderPen = new Pen(borderColor, BorderWidth);
            Pen titleBorderPen = new Pen(titleBorderColor, BorderWidth);

            GraphicsPath path1 = PaintHelper.CreatePath(boxRect, radius);
            GraphicsPath path2 = PaintHelper.CreatePath(textRect, titleRadius);

            Brush basebrush = new SolidBrush(this.BaseColor);
            Brush titleBasebrush = new SolidBrush(this.TitleBaseColor);
            Brush textbrush = new SolidBrush(this.ForeColor);
            Brush backbrush = new SolidBrush(this.BackColor);

            g.FillPath(basebrush, path1);
            g.DrawPath(borderPen, path1);
            path1.AddRectangle(new Rectangle(-1, -1, this.Width + 1, this.Height + 1));
            g.FillPath(backbrush, path1);

            g.FillPath(titleBasebrush, path2);
            g.DrawPath(titleBorderPen, path2);

            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;
            g.DrawString(this.Text, this.Font, textbrush, textRect, stringFormat);

            borderPen.Dispose();
            titleBorderPen.Dispose();
            basebrush.Dispose();
            titleBasebrush.Dispose();
            textbrush.Dispose();
            backbrush.Dispose();

            path1.Dispose();
            path2.Dispose();

            borderPen.Dispose();
            titleBorderPen.Dispose();
        }
    }
}